import 'package:flutter/material.dart';

class MutilSimpleBuilderExample extends StatefulWidget {
  const MutilSimpleBuilderExample({super.key});

  @override
  State<MutilSimpleBuilderExample> createState() =>
      _MutilSimpleBuilderExampleState();
}

class _MutilSimpleBuilderExampleState extends State<MutilSimpleBuilderExample> {
  MyNotifier n1 = MyNotifier();
  MyNotifier n2 = MyNotifier();

  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.runtimeType.toString()),
      ),
      body: Column(
        children: <Widget>[
          TextButton(
            onPressed: () => _add(n1),
            child: const Text('Use notifier 1'),
          ),
          TextButton(
            onPressed: () => _add(n2),
            child: const Text('Use notifier 2'),
          ),
          MutilSimpleBuilder(
            builder: () {
              return Text(_counter.toString());
            },
            listenables: <Listenable>[n1, n2],
          ),
        ],
      ),
    );
  }

  void _add(MyNotifier notifier) {
    _counter++;
    notifier.notifyListeners();
  }
}

class MutilSimpleBuilder extends StatefulWidget {
  final List<Listenable> listenables;
  final ValueGetter<Widget> builder;

  const MutilSimpleBuilder({
    super.key,
    required this.listenables,
    required this.builder,
  });

  @override
  State<MutilSimpleBuilder> createState() => _MutilSimpleBuilderState();
}

class _MutilSimpleBuilderState extends State<MutilSimpleBuilder> {
  final Set<Listenable> _set = {};

  @override
  void initState() {
    super.initState();
    resetListener();
  }

  void onChange() {
    setState(() {});
  }

  void resetListener() {
    for (final l in _set.toSet()) {
      l.removeListener(onChange);
    }
    _set.clear();
    _set.addAll(widget.listenables);
    for (final l in _set) {
      l.addListener(onChange);
    }
  }

  @override
  void didUpdateWidget(MutilSimpleBuilder oldWidget) {
    super.didUpdateWidget(oldWidget);
    resetListener();
    setState(() {});
  }

  @override
  void dispose() {
    for (final l in _set.toSet()) {
      l.removeListener(onChange);
    }
    _set.clear();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    assert(widget.listenables.isNotEmpty);
    return widget.builder();
  }
}

class MyNotifier extends ChangeNotifier {
  @override
  // ignore: unnecessary_overrides
  void notifyListeners() {
    super.notifyListeners();
  }
}
